package com.hulk.dryad.manage.security.component;


import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.CommonConstants;
import com.hulk.dryad.common.constant.enums.BEC;
import com.hulk.dryad.common.util.WebUtils;
import com.hulk.dryad.manage.security.util.SecurityMessageSourceUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 异常处理 {@link AuthenticationException } 不同细化异常处理
 *
 * @author hulk
 * @date 2020-06-14
 */
@Slf4j
@Component
public class DryadAuthExceptionEntryPoint implements AuthenticationEntryPoint {


    @Override
    @SneakyThrows
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) {
        response.setCharacterEncoding(CommonConstants.UTF8);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
		response.setStatus(HttpStatus.UNAUTHORIZED.value());
		R<Object> result = authException2R(authException);
		WebUtils.renderJson(response,result);

    }


	public static R<Object> authException2R(AuthenticationException authException) {
		R<Object> result = new R<>();
		result.setMsg(authException.getMessage());
		result.setData(authException.getMessage());
		result.setCode(BEC.E_4001.getErrCode());
		//
		if (authException instanceof InsufficientAuthenticationException) {
			String code = "ExceptionTranslationFilter.insufficientAuthentication";
			String msg = SecurityMessageSourceUtil.getAccessor().getMessage(
					code, authException.getMessage());
			result.setMsg(msg);
		}
		if (authException instanceof CredentialsExpiredException) {
			String code = "AbstractUserDetailsAuthenticationProvider.credentialsExpired";
			String msg = SecurityMessageSourceUtil.getAccessor().getMessage(
					code, authException.getMessage());
			result.setMsg(msg);
		}
		if (authException instanceof UsernameNotFoundException) {
			String code = "AbstractUserDetailsAuthenticationProvider.noopBindAccount";
			String msg = SecurityMessageSourceUtil.getAccessor().getMessage(
					code, authException.getMessage());
			result.setMsg(msg);
		}

		if (authException instanceof BadCredentialsException) {
			String code = "AbstractUserDetailsAuthenticationProvider.badClientCredentials";
			String msg = SecurityMessageSourceUtil.getAccessor().getMessage(
					code, authException.getMessage());
			result.setMsg(msg);
		}
		return result;
	}

}
